今天我們要來開始踏入 Flutter 開發拉,我們先從建立專案,執行看看,並且帶大家認識 Flutter 的檔案結構。讓我們開始吧!
使用 flutter
建立專案相當容易,請打開終端機,並輸入以下指令
// flutter_playground 可以換成你想要的專案名稱
flutter create flutter_playground
這時 flutter 就會自動的幫我們建立一個以 flutter_playground
為名稱的專案。此時終端機應該會提示你可以進到方才建立的專案資料夾中,並開始執行了。不過在真的這麼做之前,我們先來看看專案的檔案結構。
我們使用 VS Code 來檢視一下這個專案。在左側的檔案總管列表中,可以看見在方才建立的專案中底下有很多資料夾,我們會一一介紹其各自的用途
flutter_playground/
├── .dart_tool/
├── .idea/
├── android/
├── assets/ -> 通常需要自行建立
├── build/
├── ios/
├── lib/
├── linux/
├── macos/
├── test/
├── web/
├── windows/
├── .gitignore
├── .metadata
├── analysis_options.yaml
├── pubspec.yaml
├── pubspec.lock
└── README.md
以下是每個資料夾的用途:
.dart_tool/
:此資料夾包含的 Dart 工具相關檔案,用於專案開發與編譯。.idea
:為另一款 IDE 工具 InterlliJ IDEA 的環境配置檔android/
:Android 平台的專案檔案,包含 Gradle 構建腳本以及原生的 Android 程式碼assets/
:存放應用程式的資源檔案,例如圖片、字體等外部的資源。需要自行建立build/
:存放編譯所生成的檔案與快取資料夾,由於是編譯自動生成的,因此我們幾乎不會動到ios/
:iOS 平台的專案檔案,包含 Xcode 的項目以及原生的 iOS 程式碼lib/
:實際開發 Flutter 應用程式碼存放的資料夾linux/
:放置linux 桌面應用程式的原生程式碼macos/
:放置 macos 桌面應用程式的原生程式碼test/
:存放測試程式碼,可以在裡面寫單元測試web/
:用於 Flutter web 開發的資料夾,包含 Web 專案的相關檔案windows/
:放置 windows 桌面應用程式的原生程式碼.gitignore
:為 Git 版本控制工具的檔案,用於指名該專案底下有哪些資料夾和檔案要忽略版本控制.metadata
:用於追蹤 Flutter 專案的屬性,Flutter 工具會依此來評估功能和升級等操作analysis_options.yaml
:配置 Dart 靜態分析工具的規則和設定。可以在此檔案中定義程式碼的風格,檢查規則來確保程式碼風格的一致性pubspec.yaml
:該應用程式的配置檔,紀錄了應用程式名稱、使用套件及對應版本的訊息pubspec.lock
:在安裝外部套件時自動生成的檔案,用於確定專案使用的依賴套件版本README.md
:用 MarkDown 語法撰寫的說明文件,通常在建立專案時都會有此文件用於說明該專案如何運行、使用說明在認識完每個資料的各字用途後,我們其實不難發現其實 Flutter 本身的專案結構已經非常完整了。當然啊,安裝這麼麻煩一定要夠完整的吧XD
請使用 VS Code打開 /lib/main.dart
這個檔案,這是我們整個應用程式的起始點。原則上你現在一進到 main.dart
這個檔案,應該預設是寫滿一大堆的註解,註解的內容大體上都是在幫助我們更認識這個新東西。
我們先直接把專案跑起來看看,不過在執行專案之前,可以先用 VS Code 的搜尋框輸入>Flutter: Select Device
,並選擇該選項。
此時會跳出當前電腦中可使用的虛擬機以及連接中的裝置。如下圖目前我的電腦若是選擇上方的 macOS 則會將該專案運用 macOS 原生的 APP 型式顯示;Chrome 則是將專案以 Web 形式運行。若要使用虛擬機則點擊下方的任一虛擬機,便會成功開啟。
這裡我選擇使用 iOS 虛擬機來進行,此時就可以點擊 VS Code 右上方的 Start Debugging 或是在終端機中輸入 flutter run
來執行專案。
當你成功啟動之後,除了虛擬機已經在執行應用程式外,也會在你的 VS Code 顯示一個 Widget Inspector
的視窗。在 Flutter 的世界中,所有視覺、控制相關的都被稱作 Widget,這些 Widget 也會有階層關係。
舉例來說,我想要製作一個帶有 icon 的按鈕,於是我將 Icon
這個 widget 放進 Button
的 widget,因此 Button
的 child 就是 Icon
。可想而知,當應用程式越放越多 Widget 後,可以繪製成一張 Widget Tree,用以記錄各 widget 之間的階層關係。而 Widget Inspector
就是用於視覺化 widget trees 常用的工具。
其實這套工具可以做的事情還很多,從檢視 Layout 之間的、調整動畫速度,甚至是檢視每個 widget 的屬性等等,不過因為本系列文章重點並不在於此,我們不會詳加介紹這些功能,就留給各位讀者自行玩玩囉!
這裡也提供官方對於 Widget Inspector 的介紹文章,各位讀者有興趣的話不妨去看看!
專案執行起來的樣子如上圖,該示範應用程式是每當你點按右下角的 + 按鈕,便會記錄點按的次數。我們來稍微地進行些修改,順便看看 Flutter hot reload 的威力吧!
// 將 MyApp 這個 class 中的內容替換成以下內容
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// 原先 Colors.deepPurple 改成 Colors.blue
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
// 把 title 改成你想要的標題
home: const MyHomePage(title: 'Flutter Playground'),
);
}
}
進行以上更動之後,進行儲存後,應用程式頂部條的顏色從紫色轉為藍色,標題也轉為自己想要的文字內容,點擊的次數這個狀態也可以被保留下來。這也就是 hot reload 好的地方,無需重新啟動應用程式便能實時的看到程式碼對應用程式的更動。
Flutter 在執行 hot reload 時,會將你更動前與更動後的 Widget Tree 進行diff,並僅針對有差異的部分進行重新渲染。不過有時候往往會遇到一些情形是明明就儲存,程式碼也有變更,但畫面就是沒有更新... 這時候就要請出 Hot restart
了!
Hot restart
是運用在因某些特殊情形而導致 hot reload 不管用時候派上用場的功能之一,至於有哪些特殊情形官方也有整理一些可能需要強制 hot restart 才有辦法觸動更新的文件 (傳送門)。簡而言之,hot restart 是清楚當前應用程式的 state,重啟整個應用程式。
至於怎麼觸發 hot restart?當你執行了你的應用程式時,會看到有一系列的操作按鈕。點擊綠色的 icon 就是執行 hot restart 的方式拉。記住一個技巧:Hot reload 不管用的時候 hot restart 就好了!
最後我們為了我們教學的方便,我們要先砍掉重練,把當前的 main.dart 中的示範程式碼整個清空,因為這並不適合一開始初學者了解要怎麼從零開始寫。
所以請把整個程式碼刪除,並替換成以下的內容
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Flutter Tutorial',
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter Playground'),
),
body: const Center(
child: Text('Hello World'),
),
),
));
}
如果你的模擬器顯示的結果跟我一樣的話,那麼恭喜你,我們即將開啟我們第一個專案 Flutter Playground 的開發。
該專案不太會有實質的功能,旨在用於介紹各個常見的基礎 widget,並執行看看效果如何。
我們從今天的內容做了幾件事情:
明天開始我們會介紹幾個常見的基礎 Widget,並實際的來實現功能。我們明天再見囉~